package org.dtrd.modules.record.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.aspect.annotation.AutoLog;
import org.dtrd.common.constant.CommonConstant;
import org.dtrd.common.util.DateUtils;
import org.dtrd.config.system.Constant;
import org.dtrd.config.system.SystemState;
import org.dtrd.config.system.SystemState.ResponseState;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninRecordService;
import org.dtrd.modules.content.articles.service.IDtrdExtEmsYwTipsService;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.message.util.MsgEventPusher;
import org.dtrd.modules.record.entity.bean.DailyGroupCheckinRecord;
import org.dtrd.modules.record.entity.bean.CheckinRecord;
import org.dtrd.modules.record.entity.bean.SugarValuePhotoDetail;
import org.dtrd.modules.record.entity.request.PeriodRequest;
import org.dtrd.modules.record.entity.request.SugarPhotoPeriodRequest;
import org.dtrd.modules.record.entity.request.SugarPhotoRequest;
import org.dtrd.modules.record.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

import static org.dtrd.common.constant.CommonConstant.OPERATE_TYPE_PUSH_MESSAGE;
import static org.dtrd.common.constant.CommonConstant.OPERATE_TYPE_QUERY;

/**
 * 记录打卡
 *
 * @author 萧
 * @date:2021--19 11:06 上午
 **/
@RestController
@Slf4j
@Api(tags = "打卡记录")
@RequestMapping(value = {"/record/common", "/101/11"})
public class RecordController extends BaseController {

    @Autowired(required = false)
    private ISugarRecordService sugarRecordService;

    @Autowired(required = false)
    private IBloodPressureRecordService bloodPressureRecordService;

    @Autowired(required = false)
    private IFoodRecordService foodRecordService;

    @Autowired(required = false)
    private IHeightWeightRecordService heightWeightRecordService;

    @Autowired(required = false)
    private IInsulinRecordService insulinRecordService;

    @Autowired(required = false)
    private IKetoneRecordService ketoneRecordService;

    @Autowired(required = false)
    private IMedicalRecordService medicalRecordService;

    @Autowired(required = false)
    private ISportRecordService sportRecordService;

    @Autowired(required = false)
    private IWaistlineRecordService waistlineRecordService;

    @Autowired(required = false)
    private ISleepRecordService sleepRecordService;

    @Autowired(required = false)
    private IDtrdExtEmsYwTipsService tipsService;

    @Autowired
    private IDtrdEntRdSigninRecordService signinRecordService;

    @Autowired
    private IDtrdViewRlCheckinRecordService checkinRecordService;

    @Autowired
    private BaseCommonService baseCommonService;

    @Autowired
    private IDtrdEntRdSigninSugarValuePhotoService sugarValuePhotoService;

    @Autowired
    private INutrientRecordService nutrientRecordService;

    @Autowired
    private MsgEventPusher msgEventPusher;

    @ApiOperation("记录打卡")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Result<?> add(@RequestBody CheckinRecord checkinRecord) {
        log.info("RecordController.add record=" + checkinRecord);
        Constant.RecordType value = Constant.RecordType.valueOf(checkinRecord.getRecordType());
        Integer dataId = null, subType = checkinRecord.getSubType();
        if (subType == null) {
            checkinRecord.setSubType(0);
            subType = 0;
        }
        if (value == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_ERROR);
        } else {
            if (checkinRecord.getRecordDate() == null) {
                checkinRecord.setRecordDate(DateUtils.formatDate());
            }
            // 血糖 、饮食、用药、胰岛素、血压
            switch (value) {
                case SUGAR:
                    dataId = sugarRecordService.saveRecord(checkinRecord).getDataId();
                    if (dataId != null && dataId > 0) {
                        sugarRecordService.handleAbnormalSugarValue(checkinRecord);
                    }
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getSugarValue()).map(String::valueOf).orElse(null));
                    break;
                case BLOOD_PRESSURE:
                    dataId = bloodPressureRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getHighPressure()).map(String::valueOf).orElse(null));
                    checkinRecord.setRecordValue2(Optional.ofNullable(checkinRecord.getLowPressure()).map(String::valueOf).orElse(null));
                    checkinRecord.setRecordValue3(Optional.ofNullable(checkinRecord.getHeartPulse()).map(String::valueOf).orElse(null));
                    break;
                case SPORT:
                    dataId = sportRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getSportValue()).map(String::valueOf).orElse(null));
                    checkinRecord.setRecordDesc(checkinRecord.getSportPowerDesc());
                    break;
                case MEDICAL:
                    dataId = medicalRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getMedicalRecordStatus()).map(String::valueOf).orElse(null));
                    break;
                case DIET:
                    dataId = foodRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordDesc(checkinRecord.getFoodRecordDesc());
                    if (dataId != null && dataId > 0) {
                        msgEventPusher.signinSuccess(Constant.RecordType.DIET.getName(),checkinRecord.getRecordTime(),checkinRecord.getPatientId());
                    }
                    break;
                case WEIGHT:
                    dataId = heightWeightRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getWeight()).map(String::valueOf).orElse(null));
                    break;
                case WAIST:
                    dataId = waistlineRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getWaist()).map(String::valueOf).orElse(null));
                    break;
                case KETONE:
                    dataId = ketoneRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getKetone()).map(String::valueOf).orElse(null));
                    checkinRecord.setRecordDesc(checkinRecord.getKetoneDesc());
                    break;
                case INSULIN:
                    dataId = insulinRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getInjection()).map(String::valueOf).orElse(null));
                    checkinRecord.setRecordDesc(checkinRecord.getInsulinDescribe());
                    break;
                case SLEEP:
                    dataId = sleepRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordValue(Optional.ofNullable(checkinRecord.getSleep()).map(String::valueOf).orElse(null));
                    checkinRecord.setRecordDesc(checkinRecord.getSleepDesc());
                    break;
                case NUTRIENT:
                    dataId = nutrientRecordService.saveRecord(checkinRecord).getDataId();
                    checkinRecord.setRecordDesc(checkinRecord.getNutrientDesc());
                    break;
                default:
                    break;
            }
            log.info("RecordController.add.[record] 执行完毕  " + (dataId == null || dataId == 0 ? " 重复添加无需处理 " : ("dataId=" + dataId)));
            if (dataId != null && dataId > 0) {
                log.info("RecordController.add.[record] 添加打卡记录 dataId = " + dataId + "; recordType=" + checkinRecord.getRecordType() + "; subType=" + subType);
                signinRecordService.saveSigninRecord(dataId, checkinRecord.getPatientId(), checkinRecord.getRecordType(), subType, null);
                signinRecordService.saveSigninRecord(dataId, checkinRecord,subType, checkinRecord.getRecordDate());
                // msgEventPusher.signinSuccess(Constant.RecordType.valueOf(record.getRecordType()).getName(),record.getRecordTime(),record.getPatientId());
            }
            String logContent = String.format("记录打卡: 打卡项目: %d, 打卡子项: %d, 打卡patientId %d", checkinRecord.getRecordType(), checkinRecord.getSubType(), checkinRecord.getPatientId());
            baseCommonService.addLog(logContent, CommonConstant.LOG_TYPE_OPERATION, CommonConstant.OPERATE_TYPE_ADD);
        }
        return Result.OK(dataId);
    }

    @ApiOperation("记录打卡提示")
    @RequestMapping(value = "/getNotice", method = RequestMethod.POST)
    @AutoLog(value = "记录打卡提示", operateType = OPERATE_TYPE_PUSH_MESSAGE)
    public Result<String> getAchieveMentNotice(@RequestBody JSONObject obj) {
        log.info("RecordController.getAchieveMentNotice.[obj] " + obj);
        int noticeType = obj.getInt("type");
        Result<String> result = new Result<>();
        Constant.RecordType value = Constant.RecordType.valueOf(noticeType);
        if (value == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_ERROR);
        } else {
            result.setSuccess(true);
            switch (value) {
                case MEDICAL:
                    result.setResult("您今天进食蛋白质食物偏少，建议每天摄入肉类至少要你手掌一个掌心大小，鸡蛋一天1-2个。不能节食，蛋白质不够，免疫力就会下降，基础代谢也会下降，不利于减脂和胰岛修复。");
                    break;
                case DIET:
                    result.setResult("您今天进食蛋白质食物偏少，建议每天摄入肉类至少要你手掌一个掌心大小，鸡蛋一天1-2个。不能节食，蛋白质不够，免疫力就会下降，基础代谢也会下降，不利于减脂和胰岛修复。");
                    break;
                case INSULIN:
                    result.setResult("您今天进食蛋白质食物偏少，建议每天摄入肉类至少要你手掌一个掌心大小，鸡蛋一天1-2个。不能节食，蛋白质不够，免疫力就会下降，基础代谢也会下降，不利于减脂和胰岛修复。");
                    break;
                default:
                    break;
            }
        }
        return result;
    }

    @ApiOperation("记录小贴士")
    @RequestMapping(value = "/tips", method = RequestMethod.GET)
    @AutoLog(value = "获取记录小贴士内容", operateType = OPERATE_TYPE_QUERY)
    public Result<String> getRecordTips(@RequestParam(name = "type", defaultValue = "1") Integer type) {
        String tips = tipsService.getTipsById(type);
        return Result.OK(tips);
    }

    @ApiOperation("按时间段查询打卡记录")
    @PostMapping("/1011101")
    public Result<?> getSigninRecords(@RequestBody @Validated PeriodRequest request) {
//        if (CheckUtil.isEmpty(request.getStartTime())) {
//            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
//        }
        String endTime = request.getEndTime();

//        if (request.getPageNo() != null && request.getPageNo() > 0 && request.getPageSize() != null && request.getPageSize() > 0) {
//            //
//            String date = DateUtils.dateAdd(-request.getPageNo() * request.getPageSize(), endTime);
//            if (request.getPageNo()>1){
//                endTime = date;
//                request.setStartTime(DateUtils.dateAdd(-request.getPageNo() * request.getPageSize(), endTime));
//            }else{
//                request.setStartTime(date);
//            }
//        }
        List<DailyGroupCheckinRecord> dataList = checkinRecordService.selectCheckinRecords(request.getPatientId(), request.getStartTime(), endTime);
        String logContent = String.format("按时间段查询打卡记录，查询患者：%d", request.getPatientId());
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(dataList);
    }

    @ApiOperation("保存动态血糖照片")
    @PostMapping("/sugar/photo")
    public Result<?> saveSugarPhoto(@RequestBody @Validated SugarValuePhotoDetail request) {
        boolean result = sugarValuePhotoService.saveOrUpdateSugarValuePhoto(request);
        return result ? Result.OK() : error(ResponseState.STATE_OPERATION_FAILURE);
    }

    @ApiOperation("查询最近动态血糖照片")
    @PostMapping("/sugar/photo/info")
    public Result<?> getSugarPhotoRecord(@RequestBody @Validated SugarPhotoRequest request) {
        SugarValuePhotoDetail sugarValuePhoto = sugarValuePhotoService.getSugarValuePhoto(request.getPatientId(), request.getRecordDate());
        return sugarValuePhoto == null ? error(ResponseState.STATE_NO_RECORD) : Result.OK(sugarValuePhoto);
    }

    @ApiOperation("查询最近动态血糖照片列表")
    @PostMapping("/sugar/photo/list")
    public Result<?> getSugarPhotoRecordList(@RequestBody @Validated SugarPhotoPeriodRequest request) {
        String[] dates = handleTimePeriod(3, request.getPeriod(), request.getStartTime(), request.getEndTime());
        List<SugarValuePhotoDetail> list = sugarValuePhotoService.getSugarValuePhotoList(request.getPatientId(), dates[0], dates[1]);
        return CollectionUtils.isEmpty(list) ? error(ResponseState.STATE_NO_RECORD) : Result.OK(list);
    }

}
